/*
  Relocating loader for SIC,SIC/XE machine
  This program accepts program with .obj extension and which contains
  relocation bit mask
*/

#include<fstream.h>
#include<conio.h>
#include<string.h>
#include"hexdec.cpp"
class objinmem
{ private:
   char objcode[3];
   char addr[5];
  public:
   void setcode(char *x) 	{ strcpy(objcode,x); }
   void setaddr(char *x) 	{ strcpy(addr,x); }
   char * retaddr()	 	{ return addr; }
   void outaddr() 		{ cout<<addr; }
   void outcode() 		{ cout<<objcode; }
};

void main()
{
 objinmem objclass[200];
 char fname[30],str[80],instr[10],str1[70];
 char name[10],flength[10],reclen[3],bitmask[12][4],binstr[15];
 char staddr[12][7],recsize[10][7],temp[5],temp1[5],begaddr[10];
 int count=0,i,j,k,lenrec,cnt=0,cnt1=0,cnt2=0;
 int flag=0,n,binval;

 clrscr();
 cout<<"Enter File Name: "; cin>>fname;
 ifstream infile(fname);
 if(!infile)
  {cout<<" Error in opening file";  getch();  exit(0); }

 cout<<"Enter the starting address: ";
 cin>>begaddr;

 while(!infile.eof() && flag==0)
   { infile.getline(str,80);
	if(str[0]=='H')        // header record
	 {
	   for(i=1;i<=6;i++)
	    {name[i-1]=str[i];}	     name[6]='\0';
	   for(i=13;i<=18;i++)
	    {flength[i-13]=str[i];}  flength[i]='\0';
	  }
	 else if(str[0]=='E')   // end record
	  { flag=1; }
	 else                   // text record
	  {
	   for(i=3;i<=6;i++)
	    { temp[i-3]=str[i]; }   // temp-> start address of T record
	   temp[4]='\0';	  n=0;

	   hex(begaddr,'+',n);
	   hex(temp,'+',n);
	   n=strlen(temp);          // adding beginning address to the addr
	   if(n==3)
	    {
	     char ts[5];
	     strcpy(ts,"0");
	     strcat(ts,temp);	   strcpy(temp,ts);
	    }
	  else if(n==2)
	   {
	    char ts[5];
	    strcpy(ts,"00");
	    strcat(ts,temp);	   strcpy(temp,ts);
	   }
	  else if(n==1)
	  {
	    char ts[5];
	    strcpy(ts,"000");
	    strcat(ts,temp);    	   strcpy(temp,ts);
	  }

	  strcpy(staddr[cnt1++],temp);   //cnt1-> no:of text records
	  reclen[0]=str[7];  reclen[1]=str[8];  reclen[2]='\0';
	  strcpy(recsize[cnt++],reclen); //lenrec->length of text record

	  for(i=9;i<=11;i++)
	   { temp1[i-9]=str[i];}        // temp1 bitmask of each text record
	  temp1[4]='\0';

	  strcpy(bitmask[cnt2++],temp1);

	  binval=0;  hex(temp1,'+',binval);  itoa(binval,binstr,2);

	  int l=strlen(binstr);
	  if(l==11)
	  {char ts[15];      	   strcpy(ts,"0");
	   strcat(ts,binstr);	   strcpy(binstr,ts);}
	  else if(l==10)
	  {char ts[15];      	   strcpy(ts,"00");
	   strcat(ts,binstr);	   strcpy(binstr,ts);}
	  else if(l==9)
	  {char ts[15];      	   strcpy(ts,"000");
	   strcat(ts,binstr);	   strcpy(binstr,ts);}
	  else if(l==8)
	  {char ts[15];      	   strcpy(ts,"0000");
	   strcat(ts,binstr);	   strcpy(binstr,ts);}
	  else if(l==7)
	  {char ts[15];      	   strcpy(ts,"00000");
	   strcat(ts,binstr);	   strcpy(binstr,ts);}
	  else if(l==6)
	  {char ts[15];      	   strcpy(ts,"000000");
	   strcat(ts,binstr);	   strcpy(binstr,ts);}
	  else if(l==5)
	  {char ts[15];      	   strcpy(ts,"0000000");
	   strcat(ts,binstr);	   strcpy(binstr,ts);}
	  else if(l==4)
	  {char ts[15];      	   strcpy(ts,"00000000");
	   strcat(ts,binstr);	   strcpy(binstr,ts);}
	  else if(l==3)
	  {char ts[15];      	   strcpy(ts,"000000000");
	   strcat(ts,binstr);	   strcpy(binstr,ts);}
	  else if(l==2)
	  {char ts[15];      	   strcpy(ts,"0000000000");
	   strcat(ts,binstr);	   strcpy(binstr,ts);}
	  else if(l==1)
	  {char ts[15];      	   strcpy(ts,"00000000000");
	   strcat(ts,binstr);	   strcpy(binstr,ts);}

	  lenrec=0;
	  hex(reclen,'+',lenrec);         // converting hex-length to integer
	  int lenword=lenrec/3;           // no: of object words
	  strcpy(str1,"");
	  for(i=1;i<=lenword;i++)
	   {
	    k=0;
	    for(j=i*6+8;j<=i*6+11;j++)
	     { instr[k]=str[j]; k++;	}	    instr[k]='\0';
	    if(binstr[i]=='1')
	     { n=0;
	       hex(begaddr,'+',n);	  hex(instr,'+',n);
	       n=strlen(instr);
	       if(n==3)
		{char ts[5];    		strcpy(ts,"0");
		 strcat(ts,instr);		strcpy(instr,ts);}
	       else if(n==2)
		{char ts[5];      		strcpy(ts,"00");
		 strcat(ts,instr);		strcpy(instr,ts);}
	       else if(n==1)
		{char ts[5];     		strcpy(ts,"000");
		 strcat(ts,instr);		strcpy(instr,ts);}
	     }//end of if

	    k=0;	char ts1[8];
	    for(j=i*6+6;j<=i*6+7;j++)
	     { ts1[k]=str[j]; k++; }	ts1[k]='\0';
	    strcat(ts1,instr);
	    strcat(str1,ts1);       // str1 ->new string
	  }

	  for(i=0;i<lenrec;i++)
	   {
	    k=0;
	    for(j=i*2;j<=i*2+1;j++)
	     {instr[k]=str1[j]; k++;} 	instr[k]='\0';
	    objclass[count].setcode(instr);
	    objclass[count].setaddr(temp);
	    n=1;     hex(temp,'+',n);
	    count++;
	   }
	 }//if-else  text record
   }//while

 cout<<"\n Name of source file: "<<fname;
 cout<<"\n Program length     : "<<flength<<"\n\n";

 for(i=0;i<count;i++)
  {
   objclass[i].outaddr();  cout<<" ";
   objclass[i].outcode();  cout<<"\n";
   if(wherey()==20)
    {getch(); clrscr(); j=0;};
  }
}
